package com.ledict.casefiling.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtils {
    // spring 对redis操作的封装，使用了模板模式
    private static RedisTemplate<String, Object> redisTemplate;

    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        RedisUtils.redisTemplate = redisTemplate;
    }

    /**
     * 为key指定有效期
     * @param key
     * @param time
     * @return
     */
    public boolean expire(final String key, long time) {
        if (time > 0) {
            redisTemplate.expire(key, time, TimeUnit.SECONDS);
            return true;
        }

        return false;
    }

    /**
     * 获取key的过期时间
     * @param key
     * @return
     */
    public long getExpire(final String key) {
        return redisTemplate.getExpire(key);
    }

    public boolean hasKey(final String key) {
        return redisTemplate.hasKey(key);
    }

    public Object get(final String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    public boolean set(final String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean set(final String key, Object value, long time) {
        boolean result = false;
        if (time > 0) {
            redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            result = true;
        } else {
            result = set(key, value);
        }
        return result;
    }

    // 从redis中获取List数据
    public List<Object> getCacheList(String key) {
        BoundListOperations<String, Object> bound = redisTemplate.boundListOps(key);
        return bound.range(0, bound.size());
    }

    // 更新redis中的List数据
    public void updateCacheList(String cacheKey, List<Object> dataList) {
        redisTemplate.delete(cacheKey);

        BoundListOperations<String, Object> bound = redisTemplate.boundListOps(cacheKey);
        bound.rightPushAll(dataList.toArray());
    }

    public Map<Object, Object> getCacheMap(String cacheKey) {
        BoundHashOperations<String, Object, Object> bound = redisTemplate.boundHashOps(cacheKey);
        return bound.entries();
    }

    public void clearCache(String cacheKey) {
        redisTemplate.delete(cacheKey);
    }

    public Object getDataFromCacheMap(String cacheKey, Object key) {
        BoundHashOperations<String, Object, Object> bound = redisTemplate.boundHashOps(cacheKey);
        return bound.get(key);
    }

    public void putDataToCacheMap(String cacheKey, Object key, Object value) {
        BoundHashOperations<String, Object, Object> bound = redisTemplate.boundHashOps(cacheKey);
        bound.put(key, value);
    }

    public void putDataToCache(String cacheKey, Object value, Long expireSecond) {
        BoundValueOperations<String, Object> bound = redisTemplate.boundValueOps(cacheKey);
        bound.set(value);

        if (expireSecond > 0) {
            bound.expire(expireSecond, TimeUnit.SECONDS);
        }
    }

    public Object getDataFromCache(String cacheKey) {
        BoundValueOperations<String, Object> bound = redisTemplate.boundValueOps(cacheKey);
        return bound.get();
    }


    public Long increateData(String key, Long value) {
        BoundValueOperations<String, Object> bound = redisTemplate.boundValueOps(key);
        return bound.increment(value);
    }

    public void lpush(String key, String[] values) {
        redisTemplate.boundListOps(key).leftPushAll(values);
    }

    public List<Object> lrange(String cacheKey, int start, int end) {
        return redisTemplate.boundListOps(cacheKey).range(start, end);
    }

    public void hmset(final String cacheKey, final Map<Object, Object> value) {
        BoundHashOperations<String, Object, Object> bound = redisTemplate.boundHashOps(cacheKey);
        bound.putAll(value);
    }

    public Map<Object, Object> hmget(String cacheKey) {
        BoundHashOperations<String, Object, Object> bound = redisTemplate.boundHashOps(cacheKey);
        return bound.entries();
    }

    public String hmgetByFields(String cacheKey, String fileds) {
        BoundHashOperations<String, Object, Object> bound = redisTemplate.boundHashOps(cacheKey);
        return (String) bound.get(fileds);
    }
}
